home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 11 / AMUG BBS in a Box Volume XI (April 1994) (MacWizards).iso / Files / System7 tools / Frontier / Trig Mini-Applet.sit / Trig Mini-Applet / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-24  |  14.3 KB  |  894 lines  |  [TEXT/KAHL]

  1.  
  2. /*© Copyright 1989-1991 UserLand Software, Inc.  All Rights Reserved.*/
  3.  
  4.  
  5. #include <math.h>
  6. #include <menusharing.h>
  7.  
  8. #include <iac.h>
  9.  
  10.  
  11. #define sintoken            'sine'
  12. #define costoken            'cos '
  13. #define tantoken            'tan '
  14.  
  15. #define sinhtoken            'sinh'
  16. #define coshtoken            'cosh'
  17. #define tanhtoken            'tanh'
  18.  
  19. #define asintoken            'asin'
  20. #define acostoken            'acos'
  21. #define atantoken            'atan'
  22.  
  23. #define logtoken            'log '
  24. #define log10token            'lg10'
  25.  
  26. #define exptoken            'exp '
  27. #define abstoken            'abs '
  28. #define sqrttoken            'sqrt'
  29. #define ceiltoken            'ceil'
  30. #define floortoken            'floo'
  31. #define modtoken            'mod '
  32.  
  33. #define setmessagetoken        'smsg'
  34.  
  35. int errno; /*see math.c*/
  36.  
  37.  
  38. #define applemenu 128 /*the resource id of the apple menu*/
  39.  
  40. #define aboutitem 1 /*the about command*/
  41.  
  42. #define filemenu 129 /*resource id of file menu, shared menus appear to right of this*/
  43.  
  44. #define firstsharedmenu filemenu+1 /*resource id for first shared menu*/
  45.  
  46. #define quititem 1 /*the single item in the file menu -- this is a very simple program!*/
  47.  
  48. MenuHandle happlemenu, hfilemenu; /*the two fixed, non-shared menus in this program*/
  49.  
  50. WindowPtr mainwindow = nil; /*the menu sharing test window*/
  51.  
  52. Str255 windowmessage; /*the message that's displayed in the main window*/
  53.  
  54. short flexitmainloop = false; /*when true we fall thru the main event loop*/
  55.     
  56.     
  57.  
  58.  
  59. static void copystring (Str255 source, Str255 dest) {
  60.  
  61.     /*
  62.     create a copy of source in dest.  copy the length byte and
  63.     all the characters in the source string.
  64.  
  65.     assume the strings are pascal strings, with the length byte in
  66.     the first character of the string.
  67.     */
  68.  
  69.     register short i, len;
  70.     
  71.     len = (short) source [0];
  72.     
  73.     for (i = 0; i <= len; i++) 
  74.         dest [i] = source [i];
  75.     } /*copystring*/
  76.  
  77.  
  78. static void ellipsize (Str255 s, short width) {
  79.  
  80.     /*
  81.     if the string fits inside the given number of pixels, fine -- do nothing
  82.     and return.
  83.     
  84.     if not, return a string that does fit, with ellipses representing the 
  85.     deleted characters.  ellipses are generated by pressing option-semicolon.
  86.     */
  87.     
  88.     register char len;
  89.     register short newwidth;
  90.     
  91.     if ((newwidth = StringWidth (s)) <= width) /*nothing to do, the string fits*/
  92.         return;
  93.     
  94.     len = s [0]; /* current length in characters*/
  95.     
  96.     width -= CharWidth ('…'); /* subtract width of ellipses*/
  97.         
  98.     do { /*until it fits (or we run out of characters)*/
  99.     
  100.         newwidth -= CharWidth (s [len]);
  101.         
  102.         --len;
  103.     } while ((newwidth > width) && (len != 0));
  104.     
  105.     ++len; /*make room for the ellipses*/
  106.     
  107.     s [len] = '…'; 
  108.     
  109.     s [0] = (char) len;
  110.     } /*ellipsize*/
  111.  
  112.  
  113. static void centerstring (Rect r, Str255 s) {
  114.     
  115.     /*
  116.     draw the string in the current font, size and style, centered inside
  117.     the indicated rectangle.
  118.     */
  119.     
  120.     register short rh = r.bottom - r.top;
  121.     register short rw = r.right - r.left;
  122.     register short h, v;
  123.     FontInfo fi;
  124.     
  125.     GetFontInfo (&fi);
  126.     
  127.     ellipsize (s, rw); /*make sure it fits inside the rectangle, width-wise*/
  128.     
  129.     h = r.left + ((rw - StringWidth (s)) / 2);
  130.     
  131.     v = r.top + ((rh - (fi.ascent + fi.descent)) / 2) + fi.ascent;
  132.     
  133.     MoveTo (h, v);
  134.     
  135.     ClipRect (&r);
  136.     
  137.     DrawString (s);
  138.     } /*centerstring*/
  139.  
  140.  
  141. static void setfontsizestyle (short fontnum, short fontsize, short fontstyle) {
  142.  
  143.     TextFont (fontnum);
  144.     
  145.     TextSize (fontsize);
  146.     
  147.     TextFace (fontstyle);
  148.     } /*setfontsizestyle*/
  149.     
  150.     
  151. static void updatemainwindow (void) {
  152.     
  153.     Rect r;
  154.     Str255 s;
  155.     
  156.     r = (*mainwindow).portRect;
  157.     
  158.     EraseRect (&r);
  159.     
  160.     setfontsizestyle (helvetica, 12, 0);
  161.     
  162.     centerstring (r, windowmessage);
  163.     
  164.     NumToString (FreeMem () / 1024, s);
  165.     
  166.     MoveTo (r.left + 3, r.bottom - 3);
  167.     
  168.     setfontsizestyle (geneva, 9, 0);
  169.     
  170.     DrawString (s);
  171.     
  172.     DrawString ("\pK");
  173.     } /*updatemainwindow*/
  174.     
  175.     
  176. static Boolean setwindowmessage (Str255 s) {
  177.     
  178.     copystring (s, windowmessage);
  179.     
  180.     SetPort (mainwindow);
  181.     
  182.     updatemainwindow ();
  183.     
  184.     return (true);
  185.     } /*setwindowmessage*/
  186.  
  187.  
  188. static Boolean initmainwindow (void) {
  189.     
  190.     register WindowPtr w;
  191.     
  192.     w = mainwindow = GetNewWindow (128, nil, (WindowPtr) -1);
  193.     
  194.     if (w == nil)
  195.         return (false);
  196.     
  197.     ShowWindow (w);
  198.     
  199.     return (true);
  200.     } /*initmainwindow*/
  201.  
  202.  
  203. static void handleupdate (EventRecord *ev) {
  204.     
  205.     register WindowPtr w;
  206.     
  207.     w = (WindowPtr) (*ev).message;
  208.     
  209.     BeginUpdate (w);
  210.     
  211.     SetPort (w);
  212.     
  213.     updatemainwindow ();
  214.     
  215.     EndUpdate (w);
  216.     } /*handleupdate*/
  217.  
  218.  
  219. static void handledrag (EventRecord *ev, WindowPtr w) {
  220.     
  221.     Rect r;
  222.  
  223.     r = qd.screenBits.bounds; 
  224.     
  225.     r.top = r.top + GetMBarHeight (); 
  226.     
  227.     InsetRect (&r, 4, 4);
  228.     
  229.     DragWindow (w, (*ev).where, &r);
  230.     } /*handledrag*/
  231.  
  232.  
  233. static void handlemenu (long codeword) {
  234.     
  235.     register short idmenu, iditem;
  236.     
  237.     iditem = LoWord (codeword);
  238.     
  239.     idmenu = HiWord (codeword);
  240.     
  241.     if (SharedMenuHit (idmenu, iditem)) 
  242.         goto exit;
  243.     
  244.     switch (idmenu) {
  245.     
  246.         case applemenu: 
  247.             switch (iditem) {
  248.                 
  249.                 case aboutitem:
  250.                     Alert (262, nil);
  251.                     
  252.                     break;
  253.             
  254.                 default: {
  255.                 
  256.                     Str255 s;
  257.                     
  258.                     GetItem (happlemenu, iditem, s);
  259.                     
  260.                     OpenDeskAcc (s);
  261.                     
  262.                     break;
  263.                     }
  264.                 } /*switch*/
  265.             
  266.             break; /*apple menu*/
  267.  
  268.         case filemenu: 
  269.             switch (iditem) {
  270.                 
  271.                 case quititem:
  272.                 
  273.                     flexitmainloop = true;
  274.                     
  275.                     break;
  276.                 } /*switch*/
  277.             
  278.             break; /*file menu*/
  279.             
  280.         } /*switching on which menu was invoked*/
  281.         
  282.     exit:
  283.     
  284.     HiliteMenu (0);
  285.     } /*handlemenu*/
  286.  
  287.  
  288. static void handlemouse (EventRecord *ev) {
  289.  
  290.     register short part;
  291.     WindowPtr w;
  292.     
  293.     part = FindWindow ((*ev).where, &w);
  294.     
  295.     if (w != nil) 
  296.     
  297.         if (w != FrontWindow ()) { /*just like all other Mac programs*/
  298.             
  299.             SelectWindow (w);
  300.                             
  301.             return; /*the mouse click is consumed by the bringtofront operation*/
  302.             }
  303.     
  304.     switch (part) {
  305.     
  306.         case inMenuBar: 
  307.             handlemenu (MenuSelect ((*ev).where)); 
  308.             
  309.             break;
  310.         
  311.         case inSysWindow:
  312.             SystemClick (ev, w); 
  313.             
  314.             break;
  315.         
  316.         case inDrag:
  317.             handledrag (ev, w);
  318.             
  319.             break;
  320.             
  321.         } /*switch*/
  322.     } /*handlemouse*/
  323.  
  324.  
  325. static void handlekeystroke (EventRecord *ev) { 
  326.  
  327.     register char ch = (*ev).message & charCodeMask;
  328.     
  329.     if (SharedScriptRunning ()) { /*cmd-period terminates the script*/
  330.     
  331.         if (((*ev).modifiers & cmdKey) && (ch == '.')) { 
  332.             
  333.             CancelSharedScript (); /*cancel the shared menu script, if one is running*/
  334.         
  335.             return;
  336.             }
  337.         }
  338.     
  339.     handlemenu (MenuKey (ch)); /*not cmd-period, process the normal way*/
  340.     } /*handlekeystroke*/
  341.  
  342.  
  343. static void handleevent (EventRecord *ev) {
  344.     
  345.     switch ((*ev).what) {
  346.     
  347.         case keyDown: case autoKey: 
  348.             handlekeystroke (ev);
  349.             
  350.             break;
  351.             
  352.         case mouseDown:
  353.             handlemouse (ev);
  354.             
  355.             break;
  356.         
  357.         case updateEvt:
  358.             handleupdate (ev);
  359.             
  360.             break;
  361.             
  362.         case kHighLevelEvent:
  363.             AEProcessAppleEvent (ev);
  364.             
  365.             break;
  366.         } /*switch*/
  367.     } /*handleevent*/
  368.  
  369.  
  370. static void maineventloop (void) {
  371.     
  372.     EventRecord ev;
  373.     
  374.     while (!flexitmainloop) {
  375.         
  376.         if (WaitNextEvent (everyEvent, &ev, 1, nil)) 
  377.             handleevent (&ev);
  378.         
  379.         CheckSharedMenus (firstsharedmenu); 
  380.         } /*while*/
  381.     } /*maineventloop*/
  382.  
  383.  
  384. static void initmenus (void) {
  385.     
  386.     /*
  387.     set up our apple and file menus.  nothing fancy.
  388.     */
  389.     
  390.     happlemenu = GetMenu (applemenu); 
  391.     
  392.     AddResMenu (happlemenu, 'DRVR'); 
  393.     
  394.     InsertMenu (happlemenu, 0); 
  395.     
  396.     hfilemenu = GetMenu (filemenu); 
  397.     
  398.     InsertMenu (hfilemenu, 0);
  399.     
  400.     DrawMenuBar ();
  401.     } /*initmenus*/
  402.  
  403.  
  404. static void initmacintosh (void) {
  405.  
  406.     /*
  407.     the magic stuff that every Macintosh application needs to do 
  408.     before doing anything else.
  409.     */
  410.  
  411.     register short i;
  412.         
  413.     MaxApplZone ();
  414.     
  415.     for (i = 0; i < 10; i++) 
  416.         MoreMasters ();
  417.     
  418.     InitGraf (&qd.thePort);
  419.     
  420.     InitFonts ();
  421.     
  422.     FlushEvents (everyEvent, 0);
  423.     
  424.     InitWindows ();
  425.     
  426.     InitMenus ();
  427.     
  428.     TEInit ();
  429.     
  430.     InitDialogs (nil);
  431.     
  432.     InitCursor ();
  433.     
  434.     for (i = 0; i < 5; i++) { /*register with Multifinder*/
  435.         
  436.         EventRecord ev;
  437.         
  438.         EventAvail (everyEvent, &ev); /*see TN180 -- splash screen*/
  439.         } /*for*/
  440.     } /*initmacintosh*/
  441.  
  442.  
  443. static Boolean setmessageverb (void) {
  444.  
  445.     Str255 s;
  446.     
  447.     if (!IACgetstringparam ((OSType) keyDirectObject, s))
  448.         return (false);
  449.     
  450.     IACreturnboolean (setwindowmessage (s));
  451.     
  452.     return (true);
  453.     } /*setmessageverb*/
  454.     
  455.  
  456. static Boolean sinverb (void) {
  457.     
  458.     double x;
  459.     
  460.     if (!IACgetdoubleparam ((OSType) keyDirectObject, &x))
  461.         return (false);
  462.         
  463.     x = sin (x);
  464.  
  465.     IACreturndouble (&x);
  466.     
  467.     return (true);
  468.     } /*sinverb*/
  469.     
  470.  
  471. static Boolean cosverb (void) {
  472.     
  473.     double x;
  474.     
  475.     if (!IACgetdoubleparam ((OSType) keyDirectObject, &x))
  476.         return (false);
  477.         
  478.     x = cos (x);
  479.  
  480.     IACreturndouble (&x);
  481.     
  482.     return (true);
  483.     } /*cosverb*/
  484.     
  485.  
  486. static Boolean tanverb (void) {
  487.     
  488.     double x;
  489.     
  490.     if (!IACgetdoubleparam ((OSType) keyDirectObject, &x))
  491.         return (false);
  492.         
  493.     x = tan (x);
  494.  
  495.     IACreturndouble (&x);
  496.     
  497.     return (true);
  498.     } /*tanverb*/
  499.     
  500.  
  501. static Boolean sinhverb (void) {
  502.     
  503.     double x;
  504.     
  505.     if (!IACgetdoubleparam ((OSType) keyDirectObject, &x))
  506.         return (false);
  507.         
  508.     x = sinh (x);
  509.  
  510.     IACreturndouble (&x);
  511.     
  512.     return (true);
  513.     } /*sinhverb*/
  514.     
  515.  
  516. static Boolean coshverb (void) {
  517.     
  518.     double x;
  519.     
  520.     if (!IACgetdoubleparam ((OSType) keyDirectObject, &x))
  521.         return (false);
  522.         
  523.     x = cosh (x);
  524.  
  525.     IACreturndouble (&x);
  526.     
  527.     return (true);
  528.     } /*coshverb*/
  529.     
  530.  
  531. static Boolean tanhverb (void) {
  532.     
  533.     double x;
  534.     
  535.     if (!IACgetdoubleparam ((OSType) keyDirectObject, &x))
  536.         return (false);
  537.         
  538.     x = tanh (x);
  539.  
  540.     IACreturndouble (&x);
  541.     
  542.     return (true);
  543.     } /*tanhverb*/
  544.     
  545.  
  546. static Boolean asinverb (void) {
  547.     
  548.     double x;
  549.     
  550.     if (!IACgetdoubleparam ((OSType) keyDirectObject, &x))
  551.         return (false);
  552.         
  553.     x = asin (x);
  554.  
  555.     IACreturndouble (&x);
  556.     
  557.     return (true);
  558.     } /*asinverb*/
  559.     
  560.  
  561. static Boolean acosverb (void) {
  562.     
  563.     double x;
  564.     
  565.     if (!IACgetdoubleparam ((OSType) keyDirectObject, &x))
  566.         return (false);
  567.         
  568.     x = acos (x);
  569.  
  570.     IACreturndouble (&x);
  571.     
  572.     return (true);
  573.     } /*acosverb*/
  574.     
  575.  
  576. static Boolean atanverb (void) {
  577.     
  578.     double x;
  579.     
  580.     if (!IACgetdoubleparam ((OSType) keyDirectObject, &x))
  581.         return (false);
  582.         
  583.     x = atan (x);
  584.  
  585.     IACreturndouble (&x);
  586.     
  587.     return (true);
  588.     } /*atanverb*/
  589.     
  590.  
  591. static Boolean logverb (void) {
  592.     
  593.     double x;
  594.     
  595.     if (!IACgetdoubleparam ((OSType) keyDirectObject, &x))
  596.         return (false);
  597.         
  598.     x = log (x);
  599.  
  600.     IACreturndouble (&x);
  601.     
  602.     return (true);
  603.     } /*logverb*/
  604.     
  605.  
  606. static Boolean log10verb (void) {
  607.     
  608.     double x;
  609.     
  610.     if (!IACgetdoubleparam ((OSType) keyDirectObject, &x))
  611.         return (false);
  612.         
  613.     x = log10 (x);
  614.  
  615.     IACreturndouble (&x);
  616.     
  617.     return (true);
  618.     } /*log10verb*/
  619.     
  620.  
  621. static Boolean modverb (void) {
  622.     
  623.     double x, y;
  624.     
  625.     if (!IACgetdoubleparam ((OSType) keyDirectObject, &x))
  626.         return (false);
  627.         
  628.     if (!IACgetdoubleparam ((OSType) 'dvsr', &y))
  629.         return (false);
  630.         
  631.     x = fmod (x, y);
  632.  
  633.     IACreturndouble (&x);
  634.     
  635.     return (true);
  636.     } /*modverb*/
  637.     
  638.  
  639. static Boolean floorverb (void) {
  640.     
  641.     double x;
  642.     
  643.     if (!IACgetdoubleparam ((OSType) keyDirectObject, &x))
  644.         return (false);
  645.         
  646.     x = floor (x);
  647.  
  648.     IACreturndouble (&x);
  649.     
  650.     return (true);
  651.     } /*floorverb*/
  652.     
  653.  
  654. static Boolean ceilverb (void) {
  655.     
  656.     double x;
  657.     
  658.     if (!IACgetdoubleparam ((OSType) keyDirectObject, &x))
  659.         return (false);
  660.         
  661.     x = ceil (x);
  662.  
  663.     IACreturndouble (&x);
  664.     
  665.     return (true);
  666.     } /*ceilverb*/
  667.     
  668.  
  669. static Boolean sqrtverb (void) {
  670.     
  671.     double x;
  672.     
  673.     if (!IACgetdoubleparam ((OSType) keyDirectObject, &x))
  674.         return (false);
  675.         
  676.     x = sqrt (x);
  677.  
  678.     IACreturndouble (&x);
  679.     
  680.     return (true);
  681.     } /*sqrtverb*/
  682.     
  683.  
  684. static Boolean absverb (void) {
  685.     
  686.     double x;
  687.     
  688.     if (!IACgetdoubleparam ((OSType) keyDirectObject, &x))
  689.         return (false);
  690.         
  691.     x = fabs (x);
  692.  
  693.     IACreturndouble (&x);
  694.     
  695.     return (true);
  696.     } /*absverb*/
  697.     
  698.  
  699. static Boolean expverb (void) {
  700.     
  701.     double x;
  702.     
  703.     if (!IACgetdoubleparam ((OSType) keyDirectObject, &x))
  704.         return (false);
  705.         
  706.     x = exp (x);
  707.  
  708.     IACreturndouble (&x);
  709.     
  710.     return (true);
  711.     } /*expverb*/
  712.     
  713.  
  714. static pascal OSErr handleverb (AppleEvent *event, AppleEvent *reply, long refcon) {
  715.     
  716.     /*
  717.     called by Apple Event Manager when an 'TRIG' verb arrives.
  718.     
  719.     we always return noErr to the Apple Event Manager -- each verb processor
  720.     may set the error number and string in the reply record by calling 
  721.     IACreturnerror.
  722.     */
  723.     
  724.     if (SharedScriptCancelled (event, reply)) 
  725.         return (noErr);
  726.         
  727.     IACglobals.event = event; 
  728.     
  729.     IACglobals.reply = reply;
  730.     
  731.     IACglobals.refcon = refcon;
  732.         
  733.     switch (IACgetverbtoken ()) {
  734.     
  735.         case sintoken:
  736.             sinverb (); break;
  737.             
  738.         case costoken:
  739.             cosverb (); break;
  740.             
  741.         case tantoken:
  742.             tanverb (); break;
  743.         
  744.         case sinhtoken:
  745.             sinhverb (); break;
  746.             
  747.         case coshtoken:
  748.             coshverb (); break;
  749.             
  750.         case tanhtoken:
  751.             tanhverb (); break;
  752.         
  753.         case asintoken:
  754.             asinverb (); break;
  755.             
  756.         case acostoken:
  757.             acosverb (); break;
  758.             
  759.         case atantoken:
  760.             atanverb (); break;
  761.         
  762.         case logtoken:
  763.             logverb (); break;
  764.             
  765.         case log10token:
  766.             log10verb (); break;
  767.         
  768.         case exptoken:
  769.             expverb (); break;
  770.             
  771.         case abstoken:
  772.             absverb (); break;
  773.             
  774.         case sqrttoken:
  775.             sqrtverb (); break;
  776.             
  777.         case ceiltoken:
  778.             ceilverb (); break;
  779.             
  780.         case floortoken:
  781.             floorverb (); break;
  782.             
  783.         case modtoken:
  784.             modverb (); break;
  785.             
  786.         case setmessagetoken:
  787.             setmessageverb (); break;
  788.  
  789.         default:
  790.             IACnothandlederror (); break;
  791.             
  792.         } /*switch*/
  793.         
  794.     return (noErr);
  795.     } /*handleverb*/
  796.     
  797.  
  798. static pascal OSErr handlequit (event, reply, refcon) AEDescList *event, *reply; long refcon; {
  799.     
  800.     /*DebugStr ("\pquitapp");*/
  801.     
  802.     flexitmainloop = true;
  803.     
  804.     return (noErr);
  805.     } /*handlequit*/
  806.     
  807.     
  808. static pascal OSErr handleopenapp (event, reply, refcon) AEDescList *event, *reply; long refcon; {
  809.     
  810.     /*DebugStr ("\popenapp");*/
  811.     
  812.     return (noErr);
  813.     } /*handleopenapp*/
  814.  
  815.  
  816. static pascal Boolean openfilespec (fs) FSSpec *fs; {
  817.  
  818.     /*DebugStr ((*fs).name);*/
  819.     
  820.     return (true);
  821.     } /*openfilespec*/
  822.     
  823.  
  824. static pascal Boolean printfilespec (fs) FSSpec *fs; {
  825.  
  826.     /*DebugStr ((*fs).name);*/
  827.     
  828.     return (true);
  829.     } /*printfilespec*/
  830.     
  831.  
  832. static pascal OSErr handleopen (AppleEvent *event, AppleEvent *reply, long refcon) {
  833.     
  834.     IACglobals.event = event;
  835.     
  836.     IACglobals.reply = reply;
  837.     
  838.     IACglobals.refcon = refcon;
  839.     
  840.     return (IACdrivefilelist (&openfilespec));
  841.     } /*handleopen*/
  842.     
  843.         
  844. static pascal OSErr handleprint (event, reply, refcon) AEDescList *event, *reply; long refcon; {
  845.     
  846.     IACglobals.event = event;
  847.     
  848.     IACglobals.reply = reply;
  849.     
  850.     IACglobals.refcon = refcon;
  851.     
  852.     return (IACdrivefilelist (&printfilespec));
  853.     } /*handleprint*/
  854.     
  855.         
  856. void main (void) {
  857.     
  858.     initmacintosh ();
  859.     
  860.     if (!InitSharedMenus ()) 
  861.         goto error;
  862.     
  863.     if (!IACinstallhandler ('TRIG', typeWildCard, (ProcPtr) handleverb))
  864.         goto error;
  865.  
  866.     if (!IACinstallhandler (kCoreEventClass, kAEOpenApplication, (ProcPtr) &handleopenapp))
  867.         goto error;
  868.     
  869.     if (!IACinstallhandler (kCoreEventClass, kAEOpenDocuments, (ProcPtr) &handleopen))
  870.         goto error;
  871.     
  872.     if (!IACinstallhandler (kCoreEventClass, kAEPrintDocuments, (ProcPtr) &handleprint))
  873.         goto error;
  874.     
  875.     if (!IACinstallhandler (kCoreEventClass, kAEQuitApplication, (ProcPtr) &handlequit))
  876.         goto error;
  877.  
  878.     initmenus ();
  879.     
  880.     initmainwindow ();
  881.     
  882.     maineventloop ();
  883.         
  884.     ExitToShell ();
  885.     
  886.     error:
  887.     
  888.     Alert (261, nil); /*this application requires system 7.0 or higher*/
  889.         
  890.     ExitToShell ();
  891.     } /*main*/
  892.  
  893.  
  894.